package com.openatc.agent.service.impl;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.openatc.agent.service.AscsDao;
import com.openatc.agent.service.FeatureRequest;
import com.openatc.agent.service.FeatureService;
import com.openatc.agent.service.GenericMsgStrategy;
import com.openatc.agent.utils.RedisTemplateUtil;
import com.openatc.comm.data.MessageData;
import com.openatc.core.model.RESTRet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.openatc.comm.common.CosntDataDefine.getresponse;

/**
 * @Classname GetFeatureAll
 * @Description 处理所有参数的上下载
 * @Date 2022/7/19 16:32
 * @Created by panleilei
 */
@Service(value = "feature/all")
public class FeatureAllRequest extends FeatureRequest {
    @Autowired
    private FeatureService featureService;

    @Autowired
    private RedisTemplateUtil redisTemplateUtil;

    @Autowired
    private CommServiceDown commServiceDown;

    @Autowired
    private AscsDao devDao;

    /**
     * 成功上载所有参数
     * @param requestData
     * @param responseData
     * @return
     */
    @Override
    public RESTRet successGetProcess(MessageData requestData, RESTRet responseData) {
        // 将参数保存到数据库
        MessageData res = (MessageData) responseData.getData();

        RESTRet restRet = featureService.saveFeatureAll(res);
        if (!restRet.isSuccess()){
            logger.warning("MsgPostHandler process: save feature failed!");
        }

        // 更新参数的缓存
        updateCache(res);
        // 更新dev表中所有统计数量
        int row = updateAllFeatureCount(res);
        if (row == 0) {
            logger.warning("update dev feature count failed!");
        }
        return super.successGetProcess(requestData, responseData);
    }

    /**
     * 成功下载所有参数
     * @param requestData
     * @param responseData
     * @return
     */
    @Override
    public RESTRet successSetProcess(MessageData requestData, RESTRet responseData) {
        // 将参数保存到数据库
        RESTRet ret = featureService.saveFeatureAll(requestData);
        if (!ret.isSuccess()){
            logger.warning("MsgPostHandler process: save feature failed!");
        }
        // 更新参数的缓存
        updateCache(requestData);
        // 更新dev表中所有统计数量
        int row = updateAllFeatureCount(requestData);
        if (row == 0) {
            logger.warning("update dev feature count failed!");
        }
        return super.successSetProcess(requestData, responseData);
    }

    private int updateAllFeatureCount(MessageData requestData) {
        // 计算出所有的数量，更新一次
        int phaseCount = commServiceDown.computeFeatureCount(requestData, "phaseList");
        int patternCount = commServiceDown.computeFeatureCount(requestData, "patternList");
        int planCount = commServiceDown.computeFeatureCount(requestData, "planList");
        int dateCount = commServiceDown.computeFeatureCount(requestData, "dateList");
        int overlapCount = commServiceDown.computeFeatureCount(requestData, "overlaplList");
        List<Integer> vehtypes = new ArrayList<>();
        vehtypes.add(2);
        vehtypes.add(4);
        int vehLampCount = computeLampCount(requestData,vehtypes);
        vehtypes.clear();
        vehtypes.add(3);
        vehtypes.add(5);
        int pedLampCount = computeLampCount(requestData,vehtypes);

        String sql = String.format("update dev set pattern_update_time=LOCALTIMESTAMP,phase_count=%s,pattern_count=%s,plan_count=%s,date_count=%s,veh_lamp_count=%s,ped_lamp_count=%s," +
                        "overlap_count=%s where agentid='%s'",
                phaseCount,patternCount,planCount,dateCount,vehLampCount,pedLampCount,overlapCount,requestData.getAgentid());
        return devDao.updateAllFeatureCount(sql);
    }

    /**
     * 计算不同类型灯组的数量
     * @param requestData
     * @param types
     * @return
     */
    private int computeLampCount(MessageData requestData, List<Integer> types) {
        JsonElement data = requestData.getData();
        JsonElement channelElement = data.getAsJsonObject().get("channelList");
        if (channelElement == null) {
            return 0;
        }
        JsonArray channels = channelElement.getAsJsonArray();
        int count = 0;
        for (JsonElement channel : channels) {
            Integer controlType = channel.getAsJsonObject().get("controltype").getAsInt();
            if (types.contains(controlType)) {
                count++;
            }
        }
        return count;
    }


    /**
     * 成功下载全部参数后，更新参数的缓存
     * @param request
     */
    private void updateCache(MessageData request) {
        // 1、从所有参数中分离出单独参数
        Map<String, String> map = getRelect();
        List<MessageData> dataList = getDataList(request,map);
        Long expire = 0L;
        // 2、批量更新参数的缓存
        redisTemplateUtil.mulitSavaMessageData(dataList,expire);
        // 3 缓存特征参数
        String key = "asc:feature/all:" + request.getAgentid();
        redisTemplateUtil.setValue(key,gson.toJson(request));
    }

    /**
     * 所有参数中数组名和infotyoe的映射
     * @return
     */
    private Map<String, String> getRelect() {
        Map<String,String> map = new HashMap<>();
        // 相位参数
        String phase = "phaseList";
        String phaseInfotype = "feature/phase";
        // 方案参数
        String pattern = "patternList";
        String patternInfotype = "feature/pattern";

        map.put(phase,phaseInfotype);
        map.put(pattern,patternInfotype);

        return map;
    }

    /**
     * 获取分离出的单独参数
     * @param requestData
     * @Param paramNames
     * @return
     */
    private List<MessageData> getDataList(MessageData requestData,Map<String,String> map) {
        List<MessageData> dataList = new ArrayList<>();
        for (String paramName : map.keySet()) {
            JsonElement jsonElement = requestData.getData().getAsJsonObject().get(paramName);
            MessageData tempData = new MessageData(requestData.getAgentid(),getresponse,map.get(paramName));
            tempData.setCreatetime(requestData.getCreatetime());
            JsonObject jsonObject = new JsonObject();
            jsonObject.add(paramName,jsonElement);
            tempData.setData(jsonObject);
            dataList.add(tempData);
        }
        return dataList;
    }




}
